package repository

import (
	"context"
	"errors"

	"gorm.io/gorm"

	"BookStack/internal/domain/page"
	appErrors "BookStack/pkg/errors"
)

// PageRepository 自定义页面仓储实现
type PageRepository struct {
	db *gorm.DB
}

// NewPageRepository 创建自定义页面仓储
func NewPageRepository(db *gorm.DB) page.Repository {
	return &PageRepository{
		db: db,
	}
}

// Create 创建自定义页面
func (r *PageRepository) Create(ctx context.Context, p *page.Page) error {
	return r.db.WithContext(ctx).Create(p).Error
}

// Update 更新自定义页面
func (r *PageRepository) Update(ctx context.Context, p *page.Page) error {
	return r.db.WithContext(ctx).Save(p).Error
}

// Delete 删除自定义页面
func (r *PageRepository) Delete(ctx context.Context, id uint) error {
	return r.db.WithContext(ctx).Delete(&page.Page{}, id).Error
}

// GetByID 通过ID获取自定义页面
func (r *PageRepository) GetByID(ctx context.Context, id uint) (*page.Page, error) {
	var p page.Page
	err := r.db.WithContext(ctx).First(&p, id).Error
	if err != nil {
		if errors.Is(err, gorm.ErrRecordNotFound) {
			return nil, appErrors.New(appErrors.ErrCodePageNotFound, "")
		}
		return nil, err
	}
	return &p, nil
}

// GetBySlug 通过Slug获取自定义页面
func (r *PageRepository) GetBySlug(ctx context.Context, slug string) (*page.Page, error) {
	var p page.Page
	err := r.db.WithContext(ctx).Where("slug = ?", slug).First(&p).Error
	if err != nil {
		if errors.Is(err, gorm.ErrRecordNotFound) {
			return nil, appErrors.New(appErrors.ErrCodePageNotFound, "")
		}
		return nil, err
	}
	return &p, nil
}

// ExistsByTitle 检查标题是否已存在
func (r *PageRepository) ExistsByTitle(ctx context.Context, title string, excludeID uint) (bool, error) {
	var count int64
	query := r.db.WithContext(ctx).Model(&page.Page{}).Where("title = ?", title)
	if excludeID > 0 {
		query = query.Where("id != ?", excludeID)
	}
	err := query.Count(&count).Error
	return count > 0, err
}

// ExistsBySlug 检查Slug是否已存在
func (r *PageRepository) ExistsBySlug(ctx context.Context, slug string, excludeID uint) (bool, error) {
	var count int64
	query := r.db.WithContext(ctx).Model(&page.Page{}).Where("slug = ?", slug)
	if excludeID > 0 {
		query = query.Where("id != ?", excludeID)
	}
	err := query.Count(&count).Error
	return count > 0, err
}

// List 获取自定义页面列表
func (r *PageRepository) List(ctx context.Context, offset, limit int, status *int) ([]*page.Page, int64, error) {
	var pages []*page.Page
	var total int64

	query := r.db.WithContext(ctx).Model(&page.Page{})

	// 应用状态过滤
	if status != nil {
		query = query.Where("status = ?", *status)
	}

	// 获取总数
	if err := query.Count(&total).Error; err != nil {
		return nil, 0, err
	}

	// 查询分页数据
	if err := query.Order("id DESC").Offset(offset).Limit(limit).Find(&pages).Error; err != nil {
		return nil, 0, err
	}

	return pages, total, nil
}

// IncrementViewCount 增加浏览次数
func (r *PageRepository) IncrementViewCount(ctx context.Context, id uint) error {
	return r.db.WithContext(ctx).Model(&page.Page{}).Where("id = ?", id).
		UpdateColumn("view_count", gorm.Expr("view_count + ?", 1)).Error
}

// UpdateStatus 更新页面状态
func (r *PageRepository) UpdateStatus(ctx context.Context, id uint, status int) error {
	return r.db.WithContext(ctx).Model(&page.Page{}).Where("id = ?", id).
		Update("status", status).Error
}
